package com.adisi.bd;

import com.adisi.objetos.Documento;
import com.adisi.objetos.Perfil;
import com.adisi.objetos.TipoDocumento;
import com.adisi.objetos.Usuario;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UsuarioDatos {

	private Coneccion coneccion;
	private Connection con = null;
	
	public UsuarioDatos(){
		coneccion = new Coneccion();
		con = coneccion.conectar(); 
	}
	
	public UsuarioDatos(Connection con){
		this.con = con; 
	}
	
	/**
	 * Obtiene una lista de todas las personas que son Usuarios del sistema
	 * 
	 * @return List<Usuario>
	 */
	public List<Usuario> conseguirTodosLosUsuarios() {
		List<Usuario> listado = new ArrayList<Usuario>();

		ResultSet rs = null;
		
		CallableStatement sp = null;
		
		try {
			con = coneccion.conectar();
			
			sp = con.prepareCall("{call sp_Usuario_Select_All}");
			
			sp.execute();
			
			rs = sp.getResultSet();
			
			while (rs.next()) {
				Usuario usuario = new Usuario(
						rs.getInt("id_usuario"), 
						rs.getString("nickname"),
						rs.getString("clave"),
						rs.getString("nombre"), 
						rs.getString("apellido"));
				
				TipoDocumento td = TipoDocumento.fromInt(rs.getInt("id_tipo_documento"));
				
				usuario.setDocumento(new Documento(td, rs.getString("numero_documento"))); 
				

				listado.add(usuario);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				rs.close();
				sp.close();
				con.close();
			} catch (SQLException e) {
				System.out.println("problema al cerrar");
			}
		}
		return listado;
	}
	
	/**
	 * Obtiene una lista de todas las personas que son Usuarios del sistema con un determinado perfil
	 * 
	 * @param Perfil
	 * 
	 * @return List<Usuario>
	 */
	public List<Usuario> conseguirTodosLosUsuarios(Perfil perfil) {
		List<Usuario> listado = new ArrayList<Usuario>();
		
		ResultSet rs = null;
		
		CallableStatement sp = null;
		
		try {
			con = coneccion.conectar();
			
			sp = con.prepareCall("{call sp_Usuario_Select_All_x_Perfil(?)}");
			sp.setInt(1, perfil.getIdPerfil());
			
			sp.execute();
			
			rs = sp.getResultSet();
			
			while (rs.next()) {
				Usuario usuario = new Usuario(
						rs.getInt("id_usuario"), 
						rs.getString("nickname"),
						rs.getString("clave"),
						rs.getString("nombre"), 
						rs.getString("apellido"));
				
				TipoDocumento td = TipoDocumento.fromInt(rs.getInt("id_tipo_documento"));
				
				usuario.setDocumento(new Documento(td, rs.getString("numero_documento"))); 
				

				listado.add(usuario);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				rs.close();
				sp.close();
				con.close();
			} catch (SQLException e) {
				System.out.println("problema al cerrar");
			}
		}
		return listado;
	}	
	
	
	
	/**
	 * Obtiene los datos de 1 Usuario del sistema buscando por Id
	 * 
	 * @param Id
	 * 
	 * @return Usuario
	 */
	public Usuario conseguirUnUsuario(int idUsuario) {
		
		Usuario usuario = null;

		ResultSet rs = null;
		
		CallableStatement sp = null;
		
		try {
			con = coneccion.conectar();
			
			sp = con.prepareCall("{call sp_Usuario_Select_x_Id(?)}");
			sp.setInt(1, idUsuario);
			sp.execute();
			
			rs = sp.getResultSet();
			while (rs.next()) {
				usuario = new Usuario(
						rs.getInt("id_usuario"), 
						rs.getString("nickname"),
						rs.getString("clave"),
						rs.getString("nombre"), 
						rs.getString("apellido"));
				
				TipoDocumento td = TipoDocumento.fromInt(rs.getInt("id_tipo_documento"));
				
				usuario.setDocumento(new Documento(td, rs.getString("numero_documento"))); 

			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				rs.close();
				sp.close();
				con.close();
			} catch (SQLException e) {
				System.out.println("problema al cerrar");
			}
		}
		return usuario;
	}

	/**
	 * Obtiene los datos de 1 Usuario del sistema buscando por Nombre de Usuario
	 * 
	 * @param Id
	 * @param boolean
	 * 
	 * @return Usuario
	 */
	public Usuario conseguirUnUsuario(String nick) {
		
		Usuario usuario = null;
		
		CallableStatement sp = null;
		ResultSet rs = null;
		
		try {
			con = coneccion.conectar();
			sp = con.prepareCall("{call sp_Usuario_Select_x_Nickname(?)}");
			sp.setString(1, nick);
			sp.execute();
			rs=sp.getResultSet();
			while (rs.next()) {
				usuario = new Usuario(
						rs.getInt("id_usuario"), 
						rs.getString("nickname"),
						rs.getString("clave"),
						rs.getString("nombre"), 
						rs.getString("apellido"));

				TipoDocumento td = TipoDocumento.fromInt(rs.getInt("id_tipo_documento"));
				
				usuario.setDocumento(new Documento(td, rs.getString("numero_documento")));
				
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				rs.close();
				sp.close();
				con.close();
			} catch (SQLException e) {
				System.out.println("problema al cerrar");
			}
		}
		return usuario;
	}

	
	
	/**
	 * Graba los datos de 1 Usuario editado
	 * 
	 * @param Usuario
	 * 
	 * @return boolean
	 */
	public boolean grabarUnUsuario(Usuario usuario) {
		
		CallableStatement sp = null;
		
		boolean ok = false;

		/*
		 	@id_usuario as int,
			@nombre as varchar(50) = null,
			@apellido as varchar(50) = null,
			@id_tipo_documento as int = null,
			@numero_documento as int = null,
			@nickname as varchar(50) = null,
			@clave as varchar(50) = null
		 */
		
		
		try {
			con = coneccion.conectar();
			sp = con.prepareCall("{call sp_Usuario_Update(?,?,?,?,?,?,?)}");
			
			sp.setInt("id_usuario", usuario.getIdUsuario());
			sp.setString("nombre", usuario.getNombre());
			sp.setString("apellido", usuario.getApellido());
			sp.setInt("id_tipo_documento", usuario.getDocumento().getTipo().ordinal());
			sp.setString("nickname", usuario.getNick());
			sp.setString("clave", null);
			sp.setString("numero_documento", usuario.getDocumento().getNumero());
			
			sp.execute();  
			
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ok = true;
			try {
				sp.close();
				con.close();
			} catch (SQLException e) {
				System.out.println("problema al cerrar");
			}
		}
		return ok;
	}

	/**
	 * Borra los datos de 1 Usuario 
	 * 
	 * @param idUsuario
	 * 
	 * @return boolean
	 */
	public boolean borrarUnUsuario(int idUsuario) {
		
		CallableStatement sp = null;
		
		boolean ok = false;

		/*
		 	@id_usuario as int,
			
		 */
		
		
		try {
			con = coneccion.conectar();
			sp = con.prepareCall("{call sp_Usuario_Delete(?)}");
			
			sp.setInt("id_usuario", idUsuario);
			
			sp.execute();  
			
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ok = true;
			try {
				sp.close();
				con.close();
			} catch (SQLException e) {
				System.out.println("problema al cerrar");
			}
		}
		return ok;
	}
	
	public boolean agregarUnUsuario(Usuario usuario) {
		
		CallableStatement sp = null;
		
		boolean ok = false;

		/*
@nombre as varchar(50) = null,
@apellido as varchar(50) = null,
@id_tipo_documento as int = null,
@numero_documento as int = null,
@nickname as varchar(50) = null,
@clave as varchar(50) = null  
		 */
		
		
		try {
			con = coneccion.conectar();
			sp = con.prepareCall("{call sp_Usuario_Insert(?,?,?,?,?,?)}");
			
			sp.setString("nombre", usuario.getNombre());
			sp.setString("apellido", usuario.getApellido());
			sp.setInt("id_tipo_documento", usuario.getDocumento().getTipo().ordinal());
			sp.setString("numero_documento", usuario.getDocumento().getNumero());
			sp.setString("nickname", usuario.getNick());
			sp.setString("clave", usuario.getClave());
			
			sp.execute();  
						
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ok = true;
			try {
				sp.close();
				con.close();
			} catch (SQLException e) {
				System.out.println("problema al cerrar");
			}
		}
		return ok;
	}	
	
	/**
	 * Borra los perfiles de 1 Usuario 
	 * 
	 * @param idUsuario
	 * 
	 * @return boolean
	 */
	public boolean limpiarPerfiles(int idUsuario) {
		
		CallableStatement sp = null;
		
		boolean ok = false;

		/*
		 	@id_usuario as int,
			
		 */
		
		
		try {
			con = coneccion.conectar();
			sp = con.prepareCall("{call sp_Usuario_Perfil_Delete_All_x_Usuario(?)}");
			
			sp.setInt("id_usuario", idUsuario);
			
			sp.execute();  
			
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				sp.close();
				con.close();
			} catch (SQLException e) {
				System.out.println("problema al cerrar");
			}
		}
		return ok;
	}

	public boolean asignarUnPerfil(Usuario usuario, Perfil perfil) {
		
		CallableStatement sp = null;
		
		boolean ok = false;

		/*
@id_usuario as int = null,
@id_perfil as int = null
		 */
		
		try {
			con = coneccion.conectar();
			sp = con.prepareCall("{call sp_Usuario_Perfil_Insert(?,?)}");
			
			sp.setInt("id_usuario", usuario.getIdUsuario());
			sp.setInt("id_perfil", perfil.getIdPerfil());
			
			sp.execute();  
						
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			ok = true;
			try {
				sp.close();
				con.close();
			} catch (SQLException e) {
				System.out.println("problema al cerrar");
			}
		}
		return ok;
	}

	
	
}
